package controllers

import (
	"github.com/goravel/framework/contracts/http"
	"github.com/goravel/framework/facades"
	httpfacades "github.com/hulutech-web/http_result"
	"github.com/spf13/cast"
	"goravel/app/http/requests"
	"goravel/app/models"
)

type UserController struct {
}

func NewUserController() *UserController {
	return &UserController{
		//Inject services
	}
}

func (r *UserController) Info(ctx http.Context) http.Response {
	var user models.User
	err := facades.Auth(ctx).User(&user) // 必须是指针
	facades.Orm().Query().Model(&models.User{}).Where("id = ?", user.ID).First(&user)
	if err != nil {
		return ctx.Response().Json(http.StatusBadRequest, http.Json{
			"message": "用户不存在",
		})
	}
	return httpfacades.NewResult(ctx).Success("成功", user)
}

// Store 新增用户
// @Summary      新增用户
// @Description  新增用户
// @Tags         新增用户
// @Accept       json
// @Produce      json
// @Security ApiKeyAuth
// @Param Authorization header string false "Bearer 用户令牌"
// @Param UserRequest body requests.UserRequest true "UserRequest"
// @Success 200 {string} json "{"code":"200", "data":"response data"}"
// @Router       /api/user [post]
func (r *UserController) Store(ctx http.Context) http.Response {
	var userRequest requests.UserRequest
	errors, _ := ctx.Request().ValidateRequest(&userRequest)
	if errors != nil {
		return ctx.Response().Json(http.StatusUnprocessableEntity, http.Json{
			"errors": errors.All(),
		})
	}
	var user models.User
	//判断密码和确认密码是否相同
	if userRequest.Password != userRequest.ConfirmPassword {
		return ctx.Response().Json(http.StatusBadRequest, http.Json{
			"message": "密码和确认密码不一致",
		})
	}
	user.Mobile = userRequest.Mobile
	user.Password, _ = facades.Hash().Make(userRequest.Password)
	user.Name = userRequest.Name
	user.Area = userRequest.Area
	user.Address = userRequest.Address
	user.IdCard = userRequest.IdCard
	user.Pid = cast.ToUint(userRequest.Pid)
	user.Contact = userRequest.Contact
	user.ContactMobile = userRequest.ContactMobile
	user.ControlArr = userRequest.ControlArr
	user.IsAdmin = int(cast.ToUint(userRequest.IsAdmin))
	err := facades.Orm().Query().Model(&models.User{}).Create(&user)
	if err != nil {
		return ctx.Response().Json(http.StatusBadRequest, http.Json{
			"message": "用户创建失败",
		})
	}
	return ctx.Response().Json(http.StatusOK, http.Json{
		"message": "创建成功",
	})
}

// Update 新增用户
// @Summary      新增用户
// @Description  新增用户
// @Tags         新增用户
// @Accept       json
// @Produce      json
// @Security ApiKeyAuth
// @Param Authorization header string false "Bearer 用户令牌"
// @Param UserRequest body requests.UserRequest true "UserRequest"
// @Success 200 {string} json "{"code":"200", "data":"response data"}"
// @Router       /api/user/{id} [put]
func (r *UserController) Update(ctx http.Context) http.Response {
	id := cast.ToInt(ctx.Request().RouteInt("id"))
	var userRequest requests.UserRequest
	errors, _ := ctx.Request().ValidateRequest(&userRequest)
	if errors != nil {
		return ctx.Response().Json(http.StatusUnprocessableEntity, http.Json{
			"errors": errors.All(),
		})
	}
	var user models.User
	facades.Orm().Query().Model(&models.User{}).Where("id = ?", id).First(&user)
	if userRequest.Password != userRequest.ConfirmPassword {
		return ctx.Response().Json(http.StatusBadRequest, http.Json{
			"message": "密码和确认密码不一致",
		})
	}
	user.Mobile = userRequest.Mobile
	user.Password, _ = facades.Hash().Make(userRequest.Password)
	user.Name = userRequest.Name
	user.Area = userRequest.Area
	user.Address = userRequest.Address
	user.IdCard = userRequest.IdCard
	user.Pid = cast.ToUint(userRequest.Pid)
	user.IsAdmin = userRequest.IsAdmin
	user.Contact = userRequest.Contact
	user.ContactMobile = userRequest.ContactMobile
	user.ControlArr = userRequest.ControlArr
	err := facades.Orm().Query().Save(&user)
	if err != nil {
		return ctx.Response().Json(http.StatusBadRequest, http.Json{
			"message": "用户创建失败",
		})
	}
	return ctx.Response().Json(http.StatusOK, http.Json{
		"message": "更新成功",
	})
}

// Search 按名称或者手机号搜索,携带路由参数?name=xxx
// @Summary      按名称或者手机号搜索
// @Description  按名称或者手机号搜索
// @Tags         按名称或者手机号搜索
// @Accept       json
// @Produce      json
// @Security ApiKeyAuth
// @Param Authorization header string false "Bearer 用户令牌"
// @Param  name  query  string  false  "name"
// @Success 200 {string} json "{"code":"200", "data":"response data"}"
// @Router       /api/user/search [get]
func (r *UserController) Search(ctx http.Context) http.Response {
	name := ctx.Request().Query("name")
	var users []models.User
	if name == "" {
		var results map[string]string
		return ctx.Response().Success().Json(results)
	} else {
		facades.Orm().Query().Model(&models.User{}).Where("name like ?", "%"+name+"%").Where("is_admin=?", 2).OrWhere("mobile like ?", "%"+name+"%").
			Find(&users)
	}

	return ctx.Response().Success().Json(users)
}

func (r *UserController) Index(ctx http.Context) http.Response {
	users := []models.User{}
	facades.Orm().Query().Model(&models.User{}).Find(&users)
	request := ctx.Request()
	result, err := httpfacades.NewResult(ctx).SearchByParams(request.Queries(), map[string]interface{}{}).ResultPagination(&users)
	if err != nil {
		return nil
	}
	return result
}

// Top 顶级用户
// @Summary      顶级用户
// @Description  顶级用户
// @Tags         顶级用户
// @Accept       json
// @Produce      json
// @Security ApiKeyAuth
// @Param Authorization header string false "Bearer 用户令牌"
// @Success 200 {string} json "{"code":"200", "data":"response data"}"
// @Router       /api/user/top [get]
func (r *UserController) Top(ctx http.Context) http.Response {
	type UserReq struct {
		Users []models.User
		Total int64 `json:"total" form:"total"`
	}
	users := []models.User{}
	var total int64
	var childrenCount int
	facades.Orm().Query().Model(&models.User{}).Where("pid = ?", 0).Count(&total)
	facades.Orm().Query().Model(&models.User{}).Where("pid = ?", 0).With("Children").Find(&users)
	for _, user := range users {
		childrenCount += len(user.Children)
	}
	return ctx.Response().Success().Json(UserReq{
		Users: users,
		Total: total,
	})
}

// Children 下一级用户
// @Summary      下一级用户
// @Description  下一级用户
// @Tags         下一级用户
// @Accept       json
// @Produce      json
// @Security ApiKeyAuth
// 路由参数
// @Param id path number true "User ID" minimum(1) example(12345)
// @Param Authorization header string false "Bearer 用户令牌"
// @Success 200 {string} json "{"code":"200", "data":"response data"}"
// @Router       /api/user/{id}/children [get]
func (r *UserController) Children(ctx http.Context) http.Response {
	type UserReq struct {
		Users []models.User
		Total int64 `json:"total" form:"total"`
	}
	users := []models.User{}
	var total int64
	var childrenCount int
	facades.Orm().Query().Model(&models.User{}).Where("pid = ?", ctx.Request().RouteInt("id")).Count(&total)
	facades.Orm().Query().Model(&models.User{}).Where("pid = ?", ctx.Request().RouteInt("id")).With("Children").Find(&users)
	for _, user := range users {
		childrenCount += len(user.Children)
	}
	return ctx.Response().Success().Json(UserReq{
		Users: users,
		Total: total,
	})
}

// Destroy 删除用户
// @Summary      删除用户
// @Description  删除用户
// @Tags         删除用户
// @Accept       json
// @Produce      json
// @Security ApiKeyAuth
// 路由参数
// @Param id path number true "User ID" minimum(1) example(12345)
// @Param Authorization header string false "Bearer 用户令牌"
// @Success 200 {string} json "{"code":"200", "data":"response data"}"
// @Router       /api/user/{id} [delete]
func (r *UserController) Destroy(ctx http.Context) http.Response {
	id := ctx.Request().Input("id")
	var user models.User
	facades.Orm().Query().Where("id = ?", cast.ToInt(id)).First(&user)
	if user.ID == 0 {
		return ctx.Response().Status(http.StatusBadRequest).Json(http.Json{
			"message": "用户不存在",
		})
	}
	facades.Orm().Query().Delete(&user)
	return ctx.Response().Status(http.StatusOK).Json(http.Json{
		"message": "删除成功",
	})
}

// Show 显示用户
// @Summary      显示用户
// @Description  显示用户
// @Tags         显示用户
// @Accept       json
// @Produce      json
// @Security ApiKeyAuth
// 路由参数
// @Param id path number true "User ID" minimum(1) example(12345)
// @Param Authorization header string false "Bearer 用户令牌"
// @Success 200 {string} json "{"code":"200", "data":"response data"}"
// @Router       /api/user/{id} [get]
func (r *UserController) Show(ctx http.Context) http.Response {
	id := ctx.Request().Input("id")
	var user models.User
	facades.Orm().Query().Model(&models.User{}).Where("id = ?", id).First(&user)
	if user.ID == 0 {
		return ctx.Response().Status(http.StatusBadRequest).Json(http.Json{
			"message": "用户不存在",
		})
	}
	return ctx.Response().Status(http.StatusOK).Json(user)
}

// 修改密码
func (r *UserController) UpdatePassword(ctx http.Context) http.Response {
	type UserForm struct {
		ID       int    `json:"id"`
		Mobile   string `json:"mobile"`
		Password string `json:"password"`
	}
	var userForm UserForm
	err := ctx.Request().Bind(&userForm)
	if err != nil {
		return ctx.Response().Status(http.StatusBadRequest).Json(http.Json{
			"message": "参数错误",
		})
	}
	var user models.User
	facades.Orm().Query().Where("id = ?", userForm.ID).First(&user)
	if user.ID == 0 {
		return ctx.Response().Status(http.StatusBadRequest).Json(http.Json{
			"message": "用户不存在",
		})
	}
	user.Password, _ = facades.Hash().Make(userForm.Password)
	facades.Orm().Query().Update(&user)
	return ctx.Response().Status(http.StatusOK).Json(http.Json{
		"message": "修改成功",
	})

}

func (r *UserController) Grant(ctx http.Context) http.Response {
	var user models.User
	ctx.Request().Bind(&user)
	facades.Orm().Query().Model(&models.User{}).Where("id=?", user.ID).Update("grant_arr", user.GrantArr)
	return httpfacades.NewResult(ctx).Success("更新成功", nil)
}
